package ch.ethz.fcl.metrobuzz.algorithm.cluster;

import java.util.ArrayList;
import java.util.List;

import ch.ethz.fcl.metrobuzz.algorithm.cluster.data.IClusterData;

/**
 * @author Markus
 *
 */
public class Cluster {
	private List <IClusterData> clusterelements;
	private int clusterid;
	
	public Cluster(int clusterId){
		this.clusterid =clusterId;
		this.clusterelements = new ArrayList<IClusterData>();
	}
	
		
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((clusterelements == null) ? 0 : clusterelements.hashCode());
		result = prime * result + clusterid;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cluster other = (Cluster) obj;
		if (clusterelements == null) {
			if (other.clusterelements != null)
				return false;
		} else if (!clusterelements.equals(other.clusterelements))
			return false;
		if (clusterid != other.clusterid)
			return false;
		return true;
	}

	/**
	 * Adds a ClusterData to a Cluster. 
	 * 
	 * @param featureVector
	 */
	public void add(IClusterData featureVector) {
		this.clusterelements.add(featureVector);
	}



	/**
	 * @return number of ClusterDatas in this Cluster
	 */
	public int size() {
		return this.clusterelements.size();
	}

	/**
	 * @return
	 */
	public List<IClusterData> getClusterelements() {
		return clusterelements;
	}



	/**
	 * this returns the maximum distance that exists between to feature vectors in 
	 * this cluster. 
	 * @param dist This is the symetric distance measure used to calulate the distance between
	 * feature vectors
	 * 
	 * 
	 */
	public float getMaxIntraClusterDistance() {		
		IClusterData a;
		IClusterData b;

		float maxIntraClusterDistance =0.0f;
		for (int i= 0 ; i<this.clusterelements.size() -1 ; i++){
			a = this.clusterelements.get(i);
			for (int j = i+1 ; j<this.clusterelements.size(); j++){
				b = this.clusterelements.get(j);
				float currDist = a.distance(b);
				if (currDist > maxIntraClusterDistance){
					maxIntraClusterDistance = currDist;
				}
				
			}
		}
		return maxIntraClusterDistance;
	}
	
	public int getClusterid() {
		return clusterid;
	}



	public void setClusterid(int clusterid) {
		this.clusterid = clusterid;
	}



	/**
	 * This method counts the number of Elements that are in this cluster and
	 * also in the cluster that is passed as a parameter. In other words this
	 * counts the number of elements in the intersection of the clusters
	 * @param c  the cluster that we compare with
	 */
	public int countMutualElements(Cluster c) {
		int numberOfMutualElements = 0;
		for (IClusterData fv : this.clusterelements) {
			for(IClusterData otherFV : c.getClusterelements()){
				if (fv.equals(otherFV)){
					numberOfMutualElements++;
				}
			}
		}
		return numberOfMutualElements;
	}
}
